#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#include <sys/socket.h>
#include <dirent.h>

#include "../common/common.h"
#include "../common/vector.h"
#include "md5sum.h"
#include "../listes/filelist.h"
#include "file.h"


/**
 * Calcule la somme md5 (id unique)d'un fichier de chemain filepath.
 *
 * @return La clé calculé
 */
u_char *fmd5sum(const char *filepath){
	u_char *keyraw = MD5sum(filepath);
	u_char *key = getKeyHexa(keyraw);
	return key;
}

/**
 *Calcule les clés md5. A ne pas oublier de liberer le vecteur
 */
vector_p fmd5sum_bloc(const char *filepath, int begin, int end, int blocksize){
	//TODO : free des buffer non utilise
	vector_p v = vector_new();
	int i, begin_block = begin;
	int end_block = begin;
	int nbbloc = (end - begin) / blocksize;
	for(i = 1; i< nbbloc; i++){
		end_block += blocksize;
		//printf("begin_block %d  end_block %d\n", begin_block, end_block);
		u_char *keyraw = MD5sum_block(filepath, begin_block, end_block);
		begin_block = end_block;
		u_char *key = getKeyHexa(keyraw);
		vector_add(v, key);
		begin += blocksize;
	}

	u_char *keyraw = MD5sum_block(filepath, begin_block, end);
	u_char *key = getKeyHexa(keyraw);
	vector_add(v, key);

	return v;
}


/**
 * Renvoie taille d'un fichier, sinon -1.
 * Fonction utilisable en local
 */
int fsize(const char *filepath){
	int ret, size;
	struct stat st;
	ret = stat(filepath, &st);
	CHK_ERR(ret, "stat");
	size = st.st_size;
	return size;
}

/**
 * Obtenir le chemin d'un fichier. Cas echec renvoie NULL
 * Ne pas oublier de faire un free() après
 */
char *fpath(const char *filename, const char *dirpath){
	char *path = NULL;
	int ret;

	ret = asprintf(&path, "%s/%s\0", dirpath,filename);
	if (ret == -1)
		return NULL;
	return path;
}

int fcreat(const char* filepath){
	return 0;
}



/**
 * Renvoie le nom de fichier de clé "key".
 */
char *fgetname(const filelist_p list, const char *key){
	if (list != NULL){
		element *tmp_elt = list->first;

		while (tmp_elt != NULL){ //parcours la liste des fichiers
			if ( strcmp((char *)tmp_elt->data->key, key)== 0){ // comparaison des cles ????
				return (char *)tmp_elt->data->name;
			}
			tmp_elt = tmp_elt->next;
		}
	}
	return NULL;
}


/**
 * Remplissage de la liste de fichiers avec les informations des fichiers existant dans "dirpath"
 * (fct appelé juste apres la creation de la liste)
 */
return_t finitlist(filelist_p list, const char *dirpath,int port,char * ip){
	if(list != NULL){
		DIR *dir = opendir(dirpath);
		struct dirent *file;
		flist_init(list);//initialise la liste

		while ((file = readdir(dir)) != NULL){
			if (strcmp(file->d_name, ".")!=0 && strcmp(file->d_name, "..") != 0){
				//allocation des informations d'un fichier
				file_p info;
				info = malloc(sizeof(file_t));
				info->name = malloc(BUFSIZ);
				strcpy(info->ip,ip);
				info->port_s = port;
				memset((char *)info->name, 0, BUFSIZ);

				//remplissage des information d'un fichier
				strcpy((char *)info->name, file->d_name);
				char *filepath = fpath(file->d_name, dirpath);
				char *key = fmd5sum(filepath);
				info->key = (u_char*)key;
				info->size = fsize(filepath);
				free(filepath);

				flist_insert(list, info);
			}
		}
		closedir(dir);
		return RT_OK;
	}
	return RT_ERR;
}
